using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;

using DanielVaughan.ServiceLocation.Unity;

using Microsoft.Practices.Composite.Events;

namespace DanielVaughan.Calcium.Gui.Controls
{
	public class SplashScreenViewModel : DependencyObject
	{
		#region Version Dependency Property

		public static DependencyProperty VersionProperty
			= DependencyProperty.Register("Version", typeof(string), typeof(SplashScreenViewModel));

		[Description("The current version of the application.")]
		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public string Version
		{
			get
			{
				return (string)GetValue(VersionProperty);
			}
			set
			{
				SetValue(VersionProperty, value);
			}
		}

		#endregion

		#region Messages Dependency Property

		public static DependencyProperty MessagesProperty
			= DependencyProperty.Register("Messages", typeof(ObservableCollection<OutputMessage>), typeof(SplashScreenViewModel));

		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public ObservableCollection<OutputMessage> Messages
		{
			get
			{
				return (ObservableCollection<OutputMessage>)GetValue(MessagesProperty);
			}
			set
			{
				SetValue(MessagesProperty, value);
			}
		}

		#endregion

		#region Test Dependency Property

		public static DependencyProperty TestProperty = DependencyProperty.Register("Test", typeof(string), typeof(SplashScreenViewModel));

		[Description("PropertyDescription")]
		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public string Test
		{
			get
			{
				return (string)GetValue(TestProperty);
			}
			set
			{
				SetValue(TestProperty, value);
			}
		}

		#endregion


		#region BlurbVisible Dependency Property

		public static DependencyProperty BlurbVisibleProperty
			= DependencyProperty.Register("BlurbVisible", typeof(bool), typeof(SplashScreenViewModel), new PropertyMetadata(true));

		[Description("Whether the Calcium blurb is visible.")]
		[Browsable(true)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
		public bool BlurbVisible
		{
			get
			{
				return (bool)GetValue(BlurbVisibleProperty);
			}
			set
			{
				SetValue(BlurbVisibleProperty, value);
			}
		}

		#endregion

		readonly Thread thread;

		public SplashScreenViewModel()
		{
			Messages = new ObservableCollection<OutputMessage>();
			Test = "balaslsdfjklfadsl";
			thread = new Thread(WaitForEventAggregator);
			thread.Start();
		}

		void WaitForEventAggregator()
		{
			bool eventSubscribed = false;
			while (!eventSubscribed)
			{
				if (ServiceLocatorSingleton.Instance.IsInitialized())
				{
					IEventAggregator eventAggregator;
					eventSubscribed = ServiceLocatorSingleton.Instance.TryGetInstance<IEventAggregator>(out eventAggregator);
					if (eventSubscribed)
					{
						var outputEvent = eventAggregator.GetEvent<OutputPostedEvent>();
						outputEvent.Subscribe(OnOutputPosted);
						break;
					}
				}
				Wait(300);
			}
		}

		void OnOutputPosted(OutputMessage obj)
		{
			Dispatcher.InvokeIfRequired(() => Messages.Add(obj));
		}

		static readonly object waitLock = new object();
		/* TODO: [DV] Comment. */
		static void Wait(int delayMs)
		{
			if (delayMs > 0)
			{
				lock (waitLock)
				{
					Monitor.Wait(waitLock, delayMs);
				}
			}
		}
	}
}
